using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Xml;

namespace Newtonsoft.Json
{
	public static class JavaScriptConvert
	{
		public readonly static string True;

		public readonly static string False;

		public readonly static string Null;

		public readonly static string Undefined;

		internal static long InitialJavaScriptDateTicks;

		internal static DateTime MinimumJavaScriptDate;

		static JavaScriptConvert()
		{
			JavaScriptConvert.True = "true";
			JavaScriptConvert.False = "false";
			JavaScriptConvert.Null = "null";
			JavaScriptConvert.Undefined = "undefined";
			JavaScriptConvert.InitialJavaScriptDateTicks = (new DateTime(1970, 1, 1)).Ticks;
			JavaScriptConvert.MinimumJavaScriptDate = new DateTime(100, 1, 1);
		}

		internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
		{
			if (dateTime < JavaScriptConvert.MinimumJavaScriptDate)
			{
				dateTime = JavaScriptConvert.MinimumJavaScriptDate;
			}
			return (dateTime.Ticks - JavaScriptConvert.InitialJavaScriptDateTicks) / (long)10000;
		}

		internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
		{
			DateTime dateTime = new DateTime(javaScriptTicks * (long)10000 + JavaScriptConvert.InitialJavaScriptDateTicks);
			return dateTime;
		}

		public static XmlNode DeerializeXmlNode(string value)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			Type type = typeof(XmlDocument);
			JsonConverter[] jsonConverterArray = new JsonConverter[] { xmlNodeConverter };
			return (XmlDocument)JavaScriptConvert.DeserializeObject(value, type, jsonConverterArray);
		}

		public static object DeserializeObject(string value)
		{
			return JavaScriptConvert.DeserializeObject(value, null, null);
		}

		public static object DeserializeObject(string value, Type type)
		{
			return JavaScriptConvert.DeserializeObject(value, type, null);
		}

		public static T DeserializeObject<T>(string value)
		{
			return JavaScriptConvert.DeserializeObject<T>(value, null);
		}

		public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)JavaScriptConvert.DeserializeObject(value, typeof(T), converters);
		}

		public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			object obj;
			StringReader stringReader = new StringReader(value);
			JsonSerializer jsonSerializer = new JsonSerializer();
			if (!CollectionUtils.IsNullOrEmpty<JsonConverter>(converters))
			{
				for (int i = 0; i < (int)converters.Length; i++)
				{
					jsonSerializer.Converters.Add(converters[i]);
				}
			}
			using (JsonReader jsonReader = new JsonTextReader(stringReader))
			{
				obj = jsonSerializer.Deserialize(jsonReader, type);
			}
			return obj;
		}

		public static string SerializeObject(object value)
		{
			return JavaScriptConvert.SerializeObject(value, null);
		}

		public static string SerializeObject(object value, params JsonConverter[] converters)
		{
			StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
			JsonSerializer jsonSerializer = new JsonSerializer();
			if (!CollectionUtils.IsNullOrEmpty<JsonConverter>(converters))
			{
				for (int i = 0; i < (int)converters.Length; i++)
				{
					jsonSerializer.Converters.Add(converters[i]);
				}
			}
			using (JsonWriter jsonWriter = new JsonTextWriter(stringWriter))
			{
				jsonSerializer.Serialize(jsonWriter, value);
			}
			return stringWriter.ToString();
		}

		public static string SerializeXmlNode(XmlNode node)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return JavaScriptConvert.SerializeObject(node, new JsonConverter[] { xmlNodeConverter });
		}

		public static string ToString(DateTime value)
		{
			long javaScriptTicks = JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(value);
			return string.Concat("new Date(", javaScriptTicks, ")");
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return JavaScriptConvert.False;
			}
			return JavaScriptConvert.True;
		}

		public static string ToString(char value)
		{
			return JavaScriptConvert.ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString();
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(double value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(Guid value)
		{
			return string.Concat('\"', value.ToString("D", CultureInfo.InvariantCulture), '\"');
		}

		public static string ToString(string value)
		{
			return JavaScriptConvert.ToString(value, '\"');
		}

		public static string ToString(string value, char delimter)
		{
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, true);
		}

		public static string ToString(object value)
		{
			if (value == null)
			{
				return JavaScriptConvert.Null;
			}
			if (value is IConvertible)
			{
				IConvertible convertible = value as IConvertible;
				switch (convertible.GetTypeCode())
				{
					case TypeCode.Boolean:
					{
						return JavaScriptConvert.ToString((bool)convertible);
					}
					case TypeCode.Char:
					{
						return JavaScriptConvert.ToString((char)convertible);
					}
					case TypeCode.SByte:
					{
						return JavaScriptConvert.ToString((sbyte)convertible);
					}
					case TypeCode.Byte:
					{
						return JavaScriptConvert.ToString((byte)convertible);
					}
					case TypeCode.Int16:
					{
						return JavaScriptConvert.ToString((short)convertible);
					}
					case TypeCode.UInt16:
					{
						return JavaScriptConvert.ToString((ushort)convertible);
					}
					case TypeCode.Int32:
					{
						return JavaScriptConvert.ToString((int)convertible);
					}
					case TypeCode.UInt32:
					{
						return JavaScriptConvert.ToString((uint)convertible);
					}
					case TypeCode.Int64:
					{
						return JavaScriptConvert.ToString((long)convertible);
					}
					case TypeCode.UInt64:
					{
						return JavaScriptConvert.ToString((ulong)convertible);
					}
					case TypeCode.Single:
					{
						return JavaScriptConvert.ToString((float)convertible);
					}
					case TypeCode.Double:
					{
						return JavaScriptConvert.ToString((double)convertible);
					}
					case TypeCode.Decimal:
					{
						return JavaScriptConvert.ToString((decimal)convertible);
					}
					case TypeCode.DateTime:
					{
						return JavaScriptConvert.ToString((DateTime)convertible);
					}
					case TypeCode.String:
					{
						return JavaScriptConvert.ToString((string)convertible);
					}
				}
			}
			throw new ArgumentException(string.Format("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.", value.GetType()));
		}
	}
}